﻿#region File Description

//-----------------------------------------------------------------------------
// MagicJSON.cs
//
// Author: ITU Team3 (2012)
//-----------------------------------------------------------------------------

#endregion File Description

#region Using Statements

using System;
using System.Web.Script.Serialization;
using rentit03_server.Business;

#endregion Using Statements

namespace rentit03_server
{
    /// <summary>
    /// This class contains methods for converting to and from JSON.
    /// </summary>
    public static class MagicJSON
    {
        // JSON serializer
        private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();

        /// <summary>
        /// Deserialize a JSON object to a C# object
        /// </summary>
        /// <typeparam name="T">Type of the C# object you want to deserialize</typeparam>
        /// <param name="json">The JSON object you want to deserialize</param>
        /// <returns>A C# object of type T with the contents of the JSON object</returns>
        public static T Deserialize<T>(string json)
        {
            return (new JavaScriptSerializer()).Deserialize<T>(json);
        }

        /// <summary>
        /// Get a JSON return object for a successfull operation.
        /// </summary>
        /// <param name="value">Optional parameter for including an object in the return object. This could be the return value of the operation.</param>
        /// <param name="msg">A message to be passed in the return object</param>
        /// <returns>A JSON object representing a return object</returns>
        public static string GetJsonReturnObject(object value = null, string msg = "")
        {
            var v = String.Empty;

            if (value != null)
                v = (value is string) ? value as string : value.ToJSON();

            var r = new ReturnObject(v, msg);
            return r.ToJSON();
        }

        /// <summary>
        /// Get a JSON return object for a unsuccesfull operation.
        /// </summary>
        /// <param name="status">An error status code. <see cref="rentit03_server.Business.ReturnStatus"/> for status codes.</param>
        /// <param name="msg">A message to be passed in the return object</param>
        /// <returns>A JSON object representing a return object</returns>
        public static string GetJsonReturnObject(int status, string msg)
        {
            var r = new ReturnObject(status, msg, false);
            return r.ToJSON();
        }

        /// <summary>
        /// Extension method for serializing a C# object to a JSON object.
        /// </summary>
        /// <param name="obj">The C# object you want to serialize</param>
        /// <returns>A JSON object representing the given C# object</returns>
        public static string ToJSON(this object obj)
        {
            return Serializer.Serialize(obj);
        }

        /// <summary>
        /// Method for converting a C# exception to a JSON return object.
        /// This is used to pass exceptions to clients.
        /// <see cref="rentit03_server.Business.RentitException"/>
        /// </summary>
        /// <param name="e">The RentitException</param>
        /// <returns>A JSON object representing a return object</returns>
        public static string ToJsonReturnObject(this RentitException e)
        {
            var r = new ReturnObject((int)e.Status, e.Message);
            return r.ToJSON();
        }
    }

    /// <summary>
    /// This is the object type we use to return messages, values and error codes to clients.
    /// ReturnObjects are supposed to be converted to JSON.
    /// </summary>
    public struct ReturnObject
    {
        public ReturnObject(string value, string msg = "OK")
            : this()
        {
            Status = (int)ReturnStatus.Succes;
            Message = msg;
            Success = true;
            Value = value;
        }

        public ReturnObject(int status, string msg, bool succes = false)
            : this()
        {
            Status = status;
            Message = msg;
            Success = succes;
            Value = String.Empty;
        }

        public int Status { get; private set; }
        public string Message { get; private set; }
        public bool Success { get; private set; }
        public string Value { get; private set; }
    }
}